import { notNilEmpty } from 'qx-util';
import { PSFormulaDEFieldImpl } from './dataentity/defield/psformula-defield-impl';
import { PSInheritDEFieldImpl } from './dataentity/defield/psinherit-defield-impl';
import { PSLinkDEFieldImpl } from './dataentity/defield/pslink-defield-impl';
import { PSOne2ManyDataDEFieldImpl } from './dataentity/defield/psone2-many-data-defield-impl';
import { PSOne2OneDataDEFieldImpl } from './dataentity/defield/psone2-one-data-defield-impl';
import { PSPickupDEFieldImpl } from './dataentity/defield/pspickup-defield-impl';
import { IPSModelObject } from './ipsmodel-object';
import { IPSSysModelService } from './ipssysmodel-service';
import { IPSSystem } from './ipssystem';
import { registerModelHookTaps } from './model-hook-tap';
import { PSModelServiceImplBase } from './psmodel-service-impl-base';
import { PSSystemImpl } from './pssystem-impl';

/**
 * 模型服务
 *
 * @author chitanda
 * @date 2021-12-26 17:12:03
 * @export
 * @class PSModelServiceImpl
 * @extends {PSModelServiceImplBase}
 */
export class PSModelServiceImpl extends PSModelServiceImplBase implements IPSSysModelService {
  /**
   * 系统
   *
   * @author chitanda
   * @date 2021-12-26 16:12:35
   * @protected
   * @type {IPSSystem}
   */
  protected _system!: IPSSystem;

  /**
   * 获取应用对象
   *
   * @return {*}  {IPSApplication}
   */
  get sys(): IPSSystem {
    return this.getPSSystem();
  }

  /**
   * 获取系统模型实例
   *
   * @author chitanda
   * @date 2021-12-26 17:12:50
   * @return {*}  {IPSSystem}
   */
  getPSSystem(): IPSSystem {
    if (this._system == null) {
      const strPath = '/PSSYSTEM.json';
      const sys = this.createPSSystem();
      const model = this.loadModel(strPath);
      sys.init(this.getPSModelService('PSSystemImpl'), strPath, model);
      this._system = sys;
    }
    return this._system;
  }

  /**
   * 创建应用对象
   *
   * @protected
   * @return {*}  {IPSSystem}
   */
  protected createPSSystem(): IPSSystem {
    return new PSSystemImpl();
  }

  /**
   * 一对多关系数据集合，注意：值为对象值，不能直接用于 == 比较
   *
   * @author chitanda
   * @date 2021-12-27 11:12:48
   * @static
   */
  static readonly ONE2MANYDATA = 'ONE2MANYDATA';

  /**
   * 外键值对象，注意：值为对象值，不能直接用于 == 比较
   *
   * @author chitanda
   * @date 2021-12-27 11:12:42
   * @static
   */
  static readonly PICKUPOBJECT = 'PICKUPOBJECT';

  /**
   * 一对一关系数据对象，注意：值为对象值，不能直接用于 == 比较
   *
   * @author chitanda
   * @date 2021-12-27 11:12:34
   * @static
   */
  static readonly ONE2ONEDATA = 'ONE2ONEDATA';

  /**
   * 外键值，注意：值为对象值，不能直接用于 == 比较
   *
   * @author chitanda
   * @date 2021-12-27 11:12:29
   * @static
   */
  static readonly PICKUP = 'PICKUP';

  getRootModel(): IPSSystem {
    return this.sys;
  }

  getParentPSModelObject(relatedPSModelObject: IPSModelObject, cls: string, tryMode = true): IPSModelObject {
    if (this.sys.instanceof(cls)) {
      return this.sys;
    }
    return super.getParentPSModelObject(relatedPSModelObject, cls, tryMode);
  }

  onInit(): void {
    // 注册所有钩子
    registerModelHookTaps();
    const sys = this.getPSSystem();
    sys.getAllPSSysModelGroups();
    sys.getAllPSSysRefs();
    sys.getAllPSSystemModules();
    sys.getAllPSSysSFPlugins();
    sys.getAllPSSysDataSyncAgents();
    sys.getAllPSSysMsgQueues();
    sys.getAllPSSysMsgTempls();
    sys.getAllPSSysMsgTargets();
    sys.getAllPSSysLogics();
    sys.getAllPSSysUserRoles();
    sys.getAllPSSysUniReses();
    sys.getAllPSSysDynaModels();
    sys.getAllPSSysDTSQueues();

    const sysModules = sys.getAllPSSystemModules();
    if (sysModules) {
      for (let i = 0; i < sysModules.length; i++) {
        const module = sysModules[i];
        const entities = module.getAllPSDataEntities();
        if (entities) {
          entities.forEach(entity => {
            entity.getMinorPSDERs();
            entity.getMajorPSDERs();
            entity.getAllPSDEActions();
            entity.getAllPSDELogics();
          });
        }
      }
    }
  }

  protected createIPSDEField(parentPSModelObject: IPSModelObject, cls: string, model: IModel): IPSModelObject | null {
    // 属性类型
    const { dataType } = model;
    if (notNilEmpty(dataType)) {
      if (dataType === PSModelServiceImpl.ONE2ONEDATA) {
        return new PSOne2OneDataDEFieldImpl();
      }
      if (dataType === PSModelServiceImpl.ONE2MANYDATA) {
        return new PSOne2ManyDataDEFieldImpl();
      }
      if (dataType === PSModelServiceImpl.PICKUP) {
        return new PSPickupDEFieldImpl();
      }
    }
    if (model.linkDEField) {
      if (model.inheritDEField) {
        return new PSInheritDEFieldImpl();
      }
      return new PSLinkDEFieldImpl();
    }
    if (model.formulaDEField) {
      return new PSFormulaDEFieldImpl();
    }
    return super.createIPSDEField(parentPSModelObject, cls, model);
  }
}
